/**
 *  TextMash - simple IDE for Clojure
 *  
 *  Copyright (C) 2010 Aleksander Naszko
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package pl.olek.textmash.workspace;

import java.awt.Point;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.awt.event.MouseEvent;

import javax.swing.JTextPane;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Document;
import javax.swing.text.Highlighter;
import javax.swing.text.Position;


/**
 * Verticial selection of block of the text with
 * some simple oprations, like copy or delete
 * @author anaszko
 *
 */
public class VerticalSelection extends BoldCaret {

	private static final long serialVersionUID = 1964356230785859144L;
	Point lastPoint = new Point(0, 0);

	public void mouseMoved(MouseEvent e) {
		super.mouseMoved(e);
		lastPoint = new Point(e.getX(), e.getY());
	}

	public void mouseClicked(MouseEvent e) {
		super.mouseClicked(e);
		getComponent().getHighlighter().removeAllHighlights();
	}

	protected void moveCaret(MouseEvent e) {
		Point pt = new Point(e.getX(), e.getY());
		Position.Bias[] biasRet = new Position.Bias[1];
		int pos = getComponent().getUI().viewToModel(getComponent(), pt,
				biasRet);
		if (biasRet[0] == null) {
			biasRet[0] = Position.Bias.Forward;
		}
		if (pos >= 0) {
			moveDot(pos, biasRet[0]);
			Point start = new Point(Math.min(lastPoint.x, pt.x), Math.min(
					lastPoint.y, pt.y));
			Point end = new Point(Math.max(lastPoint.x, pt.x), Math.max(
					lastPoint.y, pt.y));
			customHighlight(start, end);
		}
	}

	@SuppressWarnings("static-access")
	protected void customHighlight(Point start, Point end) {
		try {
			getComponent().getHighlighter().removeAllHighlights();
			int y = start.y;
			int firstX = start.x;
			int lastX = end.x;

			int pos1 = getComponent().getUI().viewToModel(getComponent(),
					new Point(firstX, y));
			int pos2 = getComponent().getUI().viewToModel(getComponent(),
					new Point(lastX, y));

			getComponent().getHighlighter()
					.addHighlight(
							pos1,
							pos2,
							((DefaultHighlighter) getComponent()
									.getHighlighter()).DefaultPainter);

			y++;
			while (y < end.y) {
				int pos1new = getComponent().getUI().viewToModel(
						getComponent(), new Point(firstX, y));
				int pos2new = getComponent().getUI().viewToModel(
						getComponent(), new Point(lastX, y));
				if (pos1 != pos1new) {
					pos1 = pos1new;
					pos2 = pos2new;
					getComponent().getHighlighter().addHighlight(
							pos1,
							pos2,
							((DefaultHighlighter) getComponent()
									.getHighlighter()).DefaultPainter);
				}
				y++;
			}
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		}
	}

	public static void copy(JTextPane textPane) {
		try {
			Highlighter.Highlight[] selections = textPane.getHighlighter()
					.getHighlights();
			StringBuilder text = new StringBuilder();
			int cnt = selections.length;
			Document doc = textPane.getDocument();
			// doc.putProperty(DefaultEditorKit.EndOfLineStringProperty, "\n");
			String nline = doc.getProperty(
					DefaultEditorKit.EndOfLineStringProperty).toString();
			for (int i = 0; i < cnt; i++) {
				int start = selections[i].getStartOffset();
				int end = selections[i].getEndOffset();
				String selectedText = doc.getText(start, end - start);
				text.append(selectedText);
				text.append(nline);
			}
			StringSelection ss = new StringSelection(text.toString());
			Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss,
					null);
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		}
	}

	public static void cut(TextEditor textPane) {
		copy(textPane);
		delete(textPane);

	}

	public static void delete(TextEditor textPane) {
		try {
			Highlighter.Highlight[] selections = textPane.getHighlighter()
					.getHighlights();

			int cnt = selections.length;
			Document doc = textPane.getDocument();
			for (int i = 0; i < cnt; i++) {
				int start = selections[i].getStartOffset();
				int end = selections[i].getEndOffset();
//				System.out.println("G " + start + " " + end);
				doc.remove(start, end - start);
			}
			
			textPane.getHighlighter().removeAllHighlights();
			
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		}
	}
}
